package com.nervenets.general.utils;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.vladmihalcea.hibernate.type.util.ObjectMapperWrapper;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.LazyInitializer;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

import java.io.IOException;

/**
 * Created by joe on 2024/3/22.
 */
public final class JsonUtils {
    public static MappingJackson2HttpMessageConverter longToStringConverter() {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        ObjectMapper mapper = longToStringObjectMapper();
        converter.setObjectMapper(mapper);
        return converter;
    }

    public static ObjectMapperWrapper longToStringObjectMapperWrapper() {
        ObjectMapper mapper = longToStringObjectMapper();
        return new ObjectMapperWrapper(mapper);
    }

    private static ObjectMapper longToStringObjectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(Long.class, IdStringSerializer.instance);
        simpleModule.addSerializer(Long.TYPE, IdStringSerializer.instance);
        mapper.registerModule(simpleModule);
        mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
        mapper.addMixIn(HibernateProxy.class, IgnoreHibernateProxyMixin.class);
        return mapper;
    }

    //当数字太长的时候，前端无法解析很长的数字，以字符串返回
    static class IdStringSerializer extends JsonSerializer<Long> {
        public static final IdStringSerializer instance = new IdStringSerializer();

        @Override
        public void serialize(Long value, JsonGenerator gen, SerializerProvider serializerProvider) throws IOException {
            if (String.valueOf(value).length() > 15) {
                gen.writeString(String.valueOf(value));
            } else {
                gen.writeNumber(value);
            }
        }

    }

    // 定义混编类（Mixin），标记需要忽略的字段
    public abstract static class IgnoreHibernateProxyMixin {
        @JsonIgnore
        abstract LazyInitializer getHibernateLazyInitializer();

        @JsonIgnore
        abstract Object getImplementation();
    }
}
